#include "predicates.h"

int left_turn(const point& a, const point& b, const point& c)
{
	double left_turn = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
	if (eps * (std::abs((b.x - a.x) * (c.y - a.y)) + std::abs((b.y - a.y) * (c.x - a.x))) < left_turn)
		return 1;
	if (-(eps * (std::abs((b.x - a.x) * (c.y - a.y)) + std::abs((b.y - a.y) * (c.x - a.x)))) > left_turn)
		return -1;
	return exact_left_turn(a, b, c);
}

void value_left_turn(const point& a, const point& b, const point& c, mpq_t& result)
{
	mpq_t ax;
	mpq_init(ax);
	mpq_set_d(ax, a.x);

	mpq_t ay;
	mpq_init(ay);
	mpq_set_d(ay, a.y);

	mpq_t bx;
	mpq_init(bx);
	mpq_set_d(bx, b.x);

	mpq_t by;
	mpq_init(by);
	mpq_set_d(by, b.y);

	mpq_t cx;
	mpq_init(cx);
	mpq_set_d(cx, c.x);

	mpq_t cy;
	mpq_init(cy);
	mpq_set_d(cy, c.y);

	mpq_t tmp1;
	mpq_init(tmp1);
	mpq_sub(tmp1, bx, ax);

	mpq_t tmp2;
	mpq_init(tmp2);
	mpq_sub(tmp2, cy, ay);

	mpq_mul(result, tmp1, tmp2);

	mpq_sub(tmp1, by, ay);
	mpq_sub(tmp2, cx, ax);
	mpq_mul(tmp1, tmp1, tmp2);
	mpq_sub(result, result, tmp1);

	mpq_clear(ax); mpq_clear(bx); mpq_clear(cx); mpq_clear(ay); mpq_clear(by); mpq_clear(cy); mpq_clear(tmp1); mpq_clear(tmp2);
}

int exact_left_turn(const point& a, const point& b, const point& c)
{
	mpq_t value;
	mpq_init(value);
	value_left_turn(a, b, c, value);

	int sign = mpq_sgn(value); mpq_clear(value);

	return sign;
}